package b4.model
{
	import b4.ApplicationFacade;
	import b4.model.vo.DataVO;
	import b4.model.vo.player.Role;
	import b4.model.vo.player.Town;
	import b4.view.RoleSpriteMediator;
	import b4.view.TownSceneMediator;
	
	import flash.events.*;
	
	import org.puremvc.as3.interfaces.IProxy;
	import org.puremvc.as3.patterns.proxy.Proxy;
	import org.smartbird.Room;
	import org.smartbird.SBSEvent;
	import org.smartbird.SmartBirdClient;
	import org.smartbird.UpStreamDataObject;
	import org.smartbird.User;
    
	public class TownProxy extends Proxy implements IProxy
	{
		public static const NAME:String	= 'TownProxy';
		private var smartbirdClient:SmartBirdClient;
		
		public function TownProxy(smartbirdClient:SmartBirdClient, data:DataVO)
		{
        	super(TownProxy.NAME, data);
            this.smartbirdClient = smartbirdClient;
            smartbirdClient.addEventListener(SBSEvent.ROOM_JOIN, onRoomJoin);
            smartbirdClient.addEventListener(SBSEvent.USER_ENTER_ROOM, onUserEnterRoom);
            smartbirdClient.addEventListener(SBSEvent.USER_EXIT_ROOM, onUserExitRoom);
            smartbirdClient.addEventListener(SBSEvent.USER_VARIABLES_UPDATE, onUserVariablesUpdate);
            smartbirdClient.addEventListener(SBSEvent.ROOM_VARIABLES_UPDATE, onRoomVariablesUpdate);
		}
		
		public function setRoleDestination(posX:int, posY:int, destX:int, destY:int):void
		{
        	var upDo:UpStreamDataObject = new UpStreamDataObject();
        	upDo.method = "setRoleDestination";
        	upDo.data.posX = posX;
        	upDo.data.posY = posY;
        	upDo.data.destX = destX;
        	upDo.data.destY = destY;
        	smartbirdClient.sendUpStreamDataObject(upDo);
		}
		
        private function onUserEnterRoom(event:SBSEvent):void
        {
        	var user:User = event.params.user;
        	var room:Room = event.params.room;
        	var roleId:int = user.userVariables.roleId;
			var role:Role = vo.town.getRoleById(roleId); 
			if (role == null)
			{
				role = new Role();
				role.id = roleId;
				vo.town.addRole(role); 
			}
			role.name = user.userVariables.roleName;
			role.appearance = user.userVariables.roleAppearance;
			role.layerId = user.userVariables.roleLayerId;
			role.posX = user.userVariables.rolePos.posX;
			role.posY = user.userVariables.rolePos.posY;
			role.destX = user.userVariables.roleDest.posX;
			role.destY = user.userVariables.roleDest.posY;
			if (role.layerId == vo.town.layerId)
			{
				if (!facade.hasMediator(RoleSpriteMediator.NAME + role.id))
					facade.registerMediator(new RoleSpriteMediator(role.id));
				sendNotification(RoleSpriteMediator.SET_POS, {roleId: role.id, posX: role.posX, posY: role.posY});
				sendNotification(RoleSpriteMediator.SET_DEST, {roleId: role.id, posX: role.destX, posY: role.destY});
			}
        }
        
        private function onUserExitRoom(event:SBSEvent):void
        {
        	var user:User = event.params.user;
        	var room:Room = event.params.room;
        	var roleId:int = user.userVariables.roleId;
			var role:Role = vo.town.getRoleById(roleId); 
			if (role != null)
	        	vo.town.removeRole(role);
			if (facade.hasMediator(RoleSpriteMediator.NAME + roleId))
				facade.removeMediator(RoleSpriteMediator.NAME + roleId);
        }
        
        private function onRoomJoin(event:SBSEvent):void
        {
			var room:Room = event.params.room;
			var town:Town = vo.town;
			town.clearOtherRoles();
			town.townIndex = room.roomVariables.townIndex;
			town.itemStatus = new Object();
			for (var varName:String in room.roomVariables)
			{
				if (varName.indexOf("_") >= 0)
					town.itemStatus[varName] = room.roomVariables[varName];
			}
			
			for (var i:int = 0; i < room.userIdList.length; i++)
			{
				var userId:int = room.userIdList[i];
				var user:User = smartbirdClient.userManager.getUserById(userId);
				if (user != null)
				{
					var roleId:int = user.userVariables.roleId;
					var role:Role = town.getRoleById(roleId); 
					if (role == null)
					{
						role = new Role();
						role.id = roleId;
						town.addRole(role); 
					}
					role.name = user.userVariables.roleName;
					role.appearance = user.userVariables.roleAppearance;
					role.layerId = user.userVariables.roleLayerId;
					role.posX = user.userVariables.rolePos.posX;
					role.posY = user.userVariables.rolePos.posY;
					role.destX = user.userVariables.roleDest.posX;
					role.destY = user.userVariables.roleDest.posY;
					if (user.isItMe)
						town.layerId = role.layerId;
				}
			}
        	sendNotification(ApplicationFacade.ENTER_TOWN);
        }
        
        private function onRoomVariablesUpdate(event:SBSEvent):void
        {
        	var room:Room = event.params.room;
        	var town:Town = vo.town;
        	var variables:Object = event.params.variables;
        	for (var varName:String in variables)
        	{
				if (varName.indexOf("_") >= 0)
					town.itemStatus[varName] = room.roomVariables[varName];
        	}
        }
        
        private function onUserVariablesUpdate(event:SBSEvent):void
        {
        	var user:User = event.params.user;
        	var variables:Object = event.params.variables;
			var town:Town = vo.town;
        	var roleId:int = user.userVariables.roleId;
        	var role:Role = town.getRoleById(roleId);
        	if (role == null)
        		return;
        	for (var varName:String in variables)
        	{
        		switch (varName)
        		{
//        			case "roleName":
//        			
//        			break;
//        			case "roleAppearance":
//        			
//        			break;
					case "roleLayerId":
						role.layerId = variables.roleLayerId;
						if (user.isItMe)
						{
							if (town.layerId != role.layerId)
							{
								town.layerId = role.layerId; 
								sendNotification(TownSceneMediator.LOAD_TOWN_LAYER, {townIndex:town.townIndex, layerIndex:town.layerId});
							}
						}
						else
						{
							if (role.layerId == town.layerId)
							{
								if (!facade.hasMediator(RoleSpriteMediator.NAME + roleId))
									facade.registerMediator(new RoleSpriteMediator(roleId));
								sendNotification(RoleSpriteMediator.SET_POS, {roleId: role.id, posX: role.posX, posY: role.posY});
								sendNotification(RoleSpriteMediator.SET_DEST, {roleId: role.id, posX: role.destX, posY: role.destY});
							}
							else
							{
								if (facade.hasMediator(RoleSpriteMediator.NAME + roleId))
									facade.removeMediator(RoleSpriteMediator.NAME + roleId);
							}
						}
					break;
        			case "rolePos":
        				role.posX = variables.rolePos.posX;
        				role.posY = variables.rolePos.posY;
        				sendNotification(RoleSpriteMediator.SET_POS, {roleId: roleId, posX: role.posX, posY: role.posY});
        			break;
        			case "roleDest":
        				role.destX = variables.roleDest.posX;
        				role.destY = variables.roleDest.posY;
        				sendNotification(RoleSpriteMediator.SET_DEST, {roleId: roleId, posX: role.destX, posY: role.destY});
        			break;
        		}
        	}
        }
        
		public function get vo():DataVO
		{
			return data as DataVO;
		}
	}
}